import axios from 'axios'
// import config from "@/config"
import { getLocalToken } from '@/utils/auth'
import { encrypt, decrypt, generateKey } from "@/utils/crypto"
import { getLocalSysSecurity } from '@/utils/auth'
// 创建axios实例
const service = axios.create({
    // api的base_url
    // baseURL: process.env.BASE_API,
	baseURL: '/api',
    // baseURL: 'http://localhost:9999',
    // 请求超时时间
    timeout: 15000
})

// request拦截器
service.interceptors.request.use(async config => {
    // Do something before request is sent
    if (getLocalToken()) {
        // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
        config.headers['X-Token'] = getLocalToken()
    }
    
    //加密data数据
    if (config.data) {
        let security = getLocalSysSecurity()
        if (security && security.cryptoFlag == '1') {
            let key = generateKey()
            let data = config.data
            if(data instanceof FormData) {
                const boundaryKey = '----' + Date.now()    
                config.headers['encrypt-key'] = key
                config.headers['Content-Type'] = `multipart/form-data; boundary=${boundaryKey}` // 分隔符
                
                let formData = await makeUpFormData(data, boundaryKey)
                let enc = encrypt(formData, key, security.cryptoIv)
                config.data = enc
            } else if(typeof data == 'object') {
                config.headers['encrypt-key'] = key
                config.headers['Content-Type'] = 'application/json;charset=UTF-8'
                data = JSON.stringify(data)
                config.data = encrypt(data, key, security.cryptoIv)
            } else {
                config.headers['encrypt-key'] = key
                config.data = encrypt(data, key, security.cryptoIv)
            }
        }
   }
    return config
}, error => {
    // Do something with request error
    console.error(error) // for debug
    Promise.reject(error)
})

// respone拦截器
service.interceptors.response.use(
    response => {
        // 响应头有解密标志
        let key = response.headers['encrypt-key']
        if(key) {
            let security = getLocalSysSecurity()
            return JSON.parse(decrypt(response.data, key, security.cryptoIv))
        }
	    return response.data
    },
    error => {
        console.error(error.response ? error.response : error)
        let errorData = {
            type: 'error',
            code: error.response && error.response.status ? error.response.status: '1',
            msg: error.message ? error.message: '未知的错误',
            data: error.response && error.response.data ? error.response.data: error
        }

        // 工作流异常处理
        if(error.response && error.response.data && error.response.data.message) {
            errorData.msg = error.response.data.message
        }

        return errorData
    })

async function makeUpFormData(data, boundaryKey) {
    let boundary = '--' + boundaryKey;
    let endBoundary = boundary + '--';
    let result = [];

    for (let [key, value] of data) {
        if(value instanceof File) {
            let type = value.type || 'application/octet-stream'
            let filename = toBinString(value.name) // 解决中文乱码
            let name = key
            // 开始读取文件内容
            let text = await readFile(value)
            result.push(`${boundary}\r\n`);
            result.push(`Content-Disposition: form-data; name="${name}"; filename="${filename}"\r\n`); // 上传文件定义
            result.push(`Content-Type: ${type}\r\n`);
            result.push("\r\n");
            result.push(text);
            result.push("\r\n");
        } else {
            result.push(boundary + '\r\n');
            result.push('Content-Disposition: form-data; name="' + key + '"' + '\r\n\r\n');
            let text = toBinString(value) // 解决中文乱码
            result.push(text);
            result.push('\r\n');
        }
    }
    result.push(endBoundary); // 结尾分隔符
    
    return result.join("")
}

function readFile(file) {
    return new Promise((resolve, reject) => {
        try {
            var reader = new FileReader();
            // 当加载完成时调用onload事件处理程序
            reader.onload = function (event) {
                // event.target.result包含了从文件中读取到的内容（这里是Blob）
                var buffer = event.target.result
                resolve(buffer)
        };
            reader.readAsBinaryString(file)
        }catch(error) { 
            console.error(error)
            reject()
        }
    })
}

function toBinString(data) {
    const encoder = new TextEncoder();
    const encodedData = encoder.encode(data);
    let value = []
    for(let i = 0; i < encodedData.length; i++) {
        value.push(String.fromCharCode(encodedData[i]))
    }
    return value.join("");
}

export default service
